package com.hroze.util;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import ognl.Ognl;
import ognl.OgnlException;

import org.apache.log4j.Logger;


/**
 * @author ahoo
 * ognl工具类
 *
 */
public class OgnlUtil {
	public static Map root;
	public static Map context;
	public static final Logger log = Logger.getLogger(OgnlUtil.class);
	/**
	 * 匹配${和}之间的字符串
	 */
	public static final String regEx = "(?<=\\$\\{).+?(?=\\})"; //
	public static final String regEl = "\\$\\{(.+?)\\}"; //
	public static final Pattern p = Pattern.compile(regEl);
	static {
		init();
	}

	/**
	 * 使用完全默认的根对象和上下文编译字符串
	 * 
	 * @param text
	 *            文本
	 * @return
	 */
	public static String apply(String text) {
		return apply(text, root);
	}

	/**
	 * 使用自定义的根对象和系统默认的上下文编译字符串
	 * 
	 * @param text
	 *            文本
	 * @param root
	 *            根对象
	 * @return
	 */
	public static String apply(String text, Object root) {
		return apply(text, context, root);
	}

	/**
	 * 使用全部替换功能，替换${}内的变量
	 * 
	 * @param tpl
	 * @param name
	 * @param value
	 * @return
	 */
	public static String apply(String tpl, String name, String value) {
		String patternString = "\\$\\{" + name + "\\}";
		return tpl.replaceAll(patternString, value);
	}

	/**
	 * 直接使用map编译文本，效果如同：apply(text,root),但是不支持ognl表达式，处于扩展性的考虑，不再推荐使用本方法
	 * 
	 * @param tpl
	 *            被编译文本
	 * @param map
	 *            数据源map
	 * @deprecated 不推荐使用，ognl表达式性扩展性更强些
	 * @return
	 */
	public static String applyMap(String tpl, Map<String, String> map) {
		Matcher m = p.matcher(tpl);
		StringBuffer sb = new StringBuffer();
		while (m.find()) {
			String el = m.group(1);
			Object v = map.get(el);
			String value = "";
			if (v == null) {
				value = "";
			} else {
				value = v.toString().replaceAll("\\$", "\\\\\\$");
			}
			log.info("el:" + el);
			log.info("v:" + value);
			// 替换值
			m.appendReplacement(sb, value);
			log.info("sb = " + sb.toString());
		}
		m.appendTail(sb);
		return sb.toString();
	}

	/**
	 * 使用ognl表达式编译文本
	 * 
	 * @param text
	 * @param context
	 * @param root
	 * @return
	 */
	public static String apply(String text, Map context, Object root) {
		Matcher m = p.matcher(text);
		StringBuffer sb = new StringBuffer();
		while (m.find()) {
			String el = m.group(1);
			Object v = getValue(el, context, root);
			String value = "";
			if (v == null) {
				value = "";
			} else {
				value = v.toString().replaceAll("\\$", "\\\\\\$");
			}
			log.debug("el:" + el);
			log.debug("v:" + value);
			// 替换值
			m.appendReplacement(sb, value);
		}
		m.appendTail(sb);
		return sb.toString();
	}

	
	public static void put(Object key, Object value) {
		context.put(key, value);
	}

	public static Object get(Object key) {
		return context.get(key);
	}

	public static void init() {
		root = new HashMap();
		context = Ognl.createDefaultContext(root);
	}

	/**
	 * 使用默认的根和上下文解析表达式，解析出错时返回null
	 * 
	 * @param el
	 * @return
	 */
	public static Object getValue(String el) {
		return getValue(el, root);
	}

	/**
	 * 使用自定义的根和默认的上下文解析表达式，解析出错时返回null
	 * 
	 * @param el
	 *            表达式
	 * @param root
	 *            指定根路径
	 * @return 表达式的值
	 */
	public static Object getValue(String el, Object root) {
		return getValue(el, context, root);
	}

	public static Object getValue(String el, Map context, Object root) {

		try {
			return Ognl.getValue(el, context, root);
		} catch (OgnlException e) {
			log.error("表达式出错:", e);
		}
		return null;
	}

}
